import { AxiosInstance, AxiosResponse, AxiosError, InternalAxiosRequestConfig } from 'axios';
import { Alert } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { Response } from './model';
import { getAxiosBaseConfig } from './config';

/**
 * 设置拦截器
 * @param instance axios实例
 */
export const setupInterceptors = (instance: AxiosInstance): void => {
    const axiosBaseConfig = getAxiosBaseConfig();
  // 请求拦截器
  instance.interceptors.request.use(
    async (config: InternalAxiosRequestConfig) => {
      // 从存储中获取token
      const token = await AsyncStorage.getItem(axiosBaseConfig.authTokenName as string);
      
      if (token && config.headers) {
        config.headers.set(axiosBaseConfig.authTokenName, token);
      }
      
      return config;
    },
    (error: AxiosError) => {
      console.log('请求错误拦截器:', error);
      return Promise.reject(error);
    }
  );

  // 响应拦截器
    let timer:number | null = null;
    let isDefaultOpenErrorHandle = true;
    const defaultErrorHandler = (response : AxiosError | AxiosResponse<Response<any>>) => {
        const hiddenDefaultErrorHandler = () => isDefaultOpenErrorHandle = false;
        if(timer) clearTimeout(timer);
        timer = setTimeout(()=>{
          if(!isDefaultOpenErrorHandle) return;
          if(response.status != 200){
            return Alert.alert(
                  '错误',
                  "服务器错误，请稍后再试",
              );
          }
          switch((response as AxiosResponse<Response<any>>).data.code){
            case 401:
              axiosBaseConfig.authFailed()
              break;
            default:
              Alert.alert(
                  '提示',
                  (response as AxiosResponse<Response<any>>).data[axiosBaseConfig!.messageName] ?? '服务器未知错误，请稍后',
                  [
                    {
                      text: '确定',
                    },
                  ],
              );
          }
        },0)
        return hiddenDefaultErrorHandler
    }
  instance.interceptors.response.use((response:AxiosResponse<Response<any>>) => {
    if (response.config.responseType === 'blob') {
      return response;
    } else{
      switch (response.data?.code) {
        case axiosBaseConfig.successNetworkCode:
          return response.data?.data;
        default:
          const hiddenDefaultErrorHandler =  defaultErrorHandler(response)
          throw {...response,hiddenDefaultErrorHandler,uri:instance.getUri()}
      }
    }
  },
  (error: AxiosError) => {
    const hiddenDefaultErrorHandler =  defaultErrorHandler(error)
    throw {...error,hiddenDefaultErrorHandler,uri:instance.getUri()};
  }
)
};